package com.novelot.demo

import com.google.auto.service.AutoService
import com.novelot.demo.annotation.BindView
import java.io.IOException
import java.util.*
import javax.annotation.processing.*
import javax.lang.model.SourceVersion
import javax.lang.model.element.TypeElement
import javax.lang.model.element.VariableElement
import javax.lang.model.util.Elements
import javax.tools.Diagnostic

@AutoService(Processor::class)
class MyProcessor : AbstractProcessor() {

    private lateinit var mElementUtils: Elements
    private lateinit var mMessager: Messager
    private val mProxyMap = mutableMapOf<String, ClassCreatorProxy>()

    override fun init(processingEnv: ProcessingEnvironment) {
        super.init(processingEnv)
        mMessager = processingEnv.messager
        mElementUtils = processingEnv.elementUtils
    }

    override fun getSupportedAnnotationTypes(): MutableSet<String> {
        return Collections.singleton(BindView::class.java.canonicalName)
    }

    override fun getSupportedSourceVersion(): SourceVersion {
        return SourceVersion.latestSupported()
    }

    override fun process(annotations: MutableSet<out TypeElement>, roundEnv: RoundEnvironment): Boolean {
        mMessager.printMessage(Diagnostic.Kind.NOTE, "processing...")

        //得到相关的所有注解
        val elementsAnnotated = roundEnv.getElementsAnnotatedWith(BindView::class.java)
        elementsAnnotated.forEach {
            (it as? VariableElement)?.let {
                val classElement: TypeElement = it.enclosingElement as TypeElement
                val fullClassName = classElement.qualifiedName.toString()
                if (mProxyMap[fullClassName] == null) {
                    mProxyMap[fullClassName] = ClassCreatorProxy(mElementUtils, classElement)
                }
                val bindAnnotation = it.getAnnotation(BindView::class.java)
                val id = bindAnnotation.value
                mProxyMap[fullClassName]?.putElement(id, it)

            }
        }

        mProxyMap.forEach { (_, proxy) ->

            proxy.createJavaFile(processingEnv.filer)

        }

        return true
    }

}